///
/// $Id: console.h,v 1.4 2006/04/23 20:19:12 olegus Exp $
///

#ifndef _console_
#define _console_

#include "containers.h"
#include "storage.h"

const int MAX_CONSOLE_VARIABLE_NAME_LENGTH  = 64;
const int MAX_CONSOLE_COMMAND_NAME_LENGTH   = 64;
const int MAX_CONSOLE_STRING_LENGTH         = 1024;
const int MAX_CONSOLE_MESSAGE_ARGUMENTS     = 64;


// console argument type
enum ConsoleArgumentType_e
{   CONSOLEARG_NUMBER           // floating point number (EQUFLT)
,   CONSOLEARG_STRING           // string
};

typedef char ConsoleString_t [ MAX_CONSOLE_STRING_LENGTH ];


// console argument
struct ConsoleArgument_t
{
    ConsoleArgumentType_e   eType;
    union 
    {
        EQUFLT              fValue;
        ConsoleString_t     sValue;
    };
};


// console variable
// typed data chunk
class ConsoleVariable_c
{
public:
    char                    m_sName[ MAX_CONSOLE_VARIABLE_NAME_LENGTH ];

protected:
    ConsoleArgument_t       m_tValue;

public:
    void                    SetDouble( EQUFLT fValue );
    EQUFLT                  GetDouble();

    void                    SetInt( int iValue );
    int                     GetInt();

    void                    SetBool( bool bValue );
    bool                    GetBool();

    void                    SetString( const char * sValue );
    const char*             GetString();

    ConsoleArgumentType_e   GetType();

public:
    ConsoleVariable_c( const char * sName, ConsoleArgumentType_e eType );
};


// console message
// set of typed data arguments
class ConsoleMessage_c
{
protected:
    ConsoleArgument_t       m_dArgs[ MAX_CONSOLE_MESSAGE_ARGUMENTS ];
    int                     m_nArgs;

public:
    void                    AddArg( EQUFLT          fValue );
    void                    AddArg( int             iValue );
    void                    AddArg( bool            bValue );
    void                    AddArg( const char *    sValue );

    EQUFLT                  GetArgDouble( int iArg );
    int                     GetArgInt   ( int iArg );
    bool                    GetArgBool  ( int iArg );
    const char *            GetArgString( int iArg );

    ConsoleArgumentType_e   GetArgType  ( int iArg );
    int                     GetNumArgs  ();

    void                    Reset ();

public:
    ConsoleMessage_c();
};


// console command
// small routine that can process messages
class ConsoleCommand_c
{
public:
    char                    m_sName[ MAX_CONSOLE_COMMAND_NAME_LENGTH ];
    const char *            m_sHelpInfo;

protected:
    ConsoleArgumentType_e   m_dArgTypes[ MAX_CONSOLE_MESSAGE_ARGUMENTS ];
    int                     m_nArgs;

public:
    void                    AddArg ( ConsoleArgumentType_e eType );
    void                    AddArgs( const char * sArgs );

    ConsoleArgumentType_e   GetArgType( int iArg );
    int                     GetNumArgs();

public:
    virtual void            Execute( ConsoleMessage_c * pMessage ) = 0;

public:
    ConsoleCommand_c( const char * sName );
    ConsoleCommand_c( const char * sName, const char * sArgs );
};


extern StringHash_T< ConsoleVariable_c* >  g_dConsoleVariables; // global console variables heap
extern StringHash_T< ConsoleCommand_c * >  g_dConsoleCommands;  // global console commands heap


ConsoleVariable_c *     ConsoleGetVariable( const char * sName );
ConsoleCommand_c  *     ConsoleGetCommand ( const char * sName );

bool                    ConsoleGet ( const char * sName, EQUFLT & fValue );
bool                    ConsoleGet ( const char * sName, int & iValue );
bool                    ConsoleGet ( const char * sName, bool & bValue );
bool                    ConsoleGet ( const char * sName, const char * & sValue );

bool                    ConsoleSet ( const char * sName, EQUFLT fValue );
bool                    ConsoleSet ( const char * sName, int iValue );
bool                    ConsoleSet ( const char * sName, bool bValue );
bool                    ConsoleSet ( const char * sName, const char * sValue );

void                    ConsoleAddVariable( ConsoleVariable_c * pVar );
void                    ConsoleAddCommand ( ConsoleCommand_c  * pCmd );

void                    ConsoleDeleteVariable( ConsoleVariable_c * pVar );
void                    ConsoleDeleteCommand ( ConsoleCommand_c  * pCmd );

void                    ConsoleDelete();

bool                    ConsoleValidate   ( ConsoleCommand_c * pCmd, ConsoleMessage_c * pMsg );

bool                    ConsoleExec       ( ConsoleCommand_c * pCmd, ConsoleMessage_c * pMsg );
bool                    ConsoleExec       ( const char * sParseString );

void                    ConsoleProcessInput();

// report console contents
void                    ConsoleReportCommands ( Log_c &, const char * szPrefix );
void                    ConsoleReportVariables( Log_c &, const char * szPrefix );
void                    ConsoleDumpVariables  ( Log_c &, const char * szPrefix );


// good old macros

#define CMD_BEGIN( cmd, args, help )                                                    \
    class ConCmd_##cmd##_c : public ConsoleCommand_c                                    \
    {                                                                                   \
    public:                                                                             \
        ConCmd_##cmd##_c() : ConsoleCommand_c( #cmd, args ) { m_sHelpInfo = help; }     \
        virtual void Execute( ConsoleMessage_c * pMessage )                             \
        {

#define CMD_END \
        }       \
    }

#define CMD_ADD( cmd ) \
    ConsoleAddCommand( new ConCmd_##cmd##_c() )

#define CMD_CLASS_NAME( cmd ) ConCmd_##cmd##_c

#endif

///
/// $Id: console.h,v 1.4 2006/04/23 20:19:12 olegus Exp $
///

